package com.yst.sms;

import cn.hutool.core.util.RandomUtil;
import lombok.Setter;

import java.util.*;
import java.util.stream.Collectors;

public class Sms {

    private static Sms instance;
    public static Sms getInstance(){
        if (Objects.nonNull(instance)){
            return instance;
        }
        synchronized (Sms.class){
            if (Objects.nonNull(instance)){
                return instance;
            }
            instance=new Sms();
            return instance;
        }
    }

    private final Map<String,SmsSender> classMap;

    private final List<SmsSender> smsSenderList;

    public void register(String type,SmsInterface sender){
        if (!classMap.containsKey(type)) {
            SmsSender smsSender = new SmsSender().setSender(sender).setType(type);
            smsSenderList.add(smsSender);
            classMap.put(type, smsSender);
        }
    }

    public void unregister(String type){
        SmsSender smsSender=classMap.get(type);
        if (Objects.nonNull(smsSender)) {
            smsSenderList.remove(smsSender);
        }
    }
    Sms(){
        smsSenderList=new ArrayList<>();
        classMap=new HashMap<>();
    }

    @Setter
    private String defaultType;

    public String getDefaultType(){
        if (smsSenderList.size()==1){
            return smsSenderList.get(0).getType();
        }
        return defaultType;
    }

    public Sms configSign(String type,String appId,String secretKey){
        SmsSender smsSender=classMap.getOrDefault(type,null);
        if (Objects.nonNull(smsSender)){
            smsSender.getSender().config(appId,secretKey);
        }
        return this;
    }

    public List<String> getSupportTypes(){
        return smsSenderList.stream().map(SmsSender::getType).collect(Collectors.toList());
    }

    public synchronized void sendSms(String phone, String templateId, String... values) {
        SmsSender smsSender=null;
        if (classMap.containsKey(defaultType)){
            smsSender=classMap.get(defaultType);
        }

        if (Objects.isNull(smsSender)) {
            if (smsSenderList.size() == 1) {
                smsSender = smsSenderList.get(0);
            } else {
                int index = RandomUtil.randomInt(smsSenderList.size());
                smsSender = smsSenderList.get(index);
            }
        }

        smsSender.setLastSendTime(System.currentTimeMillis()).setSendTotal(smsSender.getSendTotal()+1);
        try {
            smsSender.getSender().sendSms(phone, templateId, values);
            smsSender.setSuccessCount(smsSender.getSuccessCount() + 1);
        }
        catch (Exception e){
            smsSender.setErrorCount(smsSender.getErrorCount()+1);
            throw e;
        }
    }

    public synchronized void sendFullSms(String phone, String templateId, String context) {
        SmsSender smsSender=null;
        if (classMap.containsKey(defaultType)){
            smsSender=classMap.get(defaultType);
        }

        if (Objects.isNull(smsSender)) {
            if (smsSenderList.size() == 1) {
                smsSender = smsSenderList.get(0);
            } else {
                int index = RandomUtil.randomInt(smsSenderList.size());
                smsSender = smsSenderList.get(index);
            }
        }
        smsSender.setLastSendTime(System.currentTimeMillis()).setSendTotal(smsSender.getSendTotal()+1);
        try {
            smsSender.getSender().sendFullSms(phone, templateId, context);
            smsSender.setSuccessCount(smsSender.getSuccessCount() + 1);
        }
        catch (Exception e){
            smsSender.setErrorCount(smsSender.getErrorCount()+1);
            throw e;
        }
    }
}
